/**
 * Created by Ysssssss on 2021/5/25.
 */
import React, {forwardRef, useState, useEffect, useCallback, useContext} from 'react'
import { Table, Radio, InputNumber, Row, Col, Modal } from "antd";
import notify from "@utils/tip";
import NP from 'number-precision'
import CustomizeModal, {CustomizeModalButton, CustomizeModalContext} from "@common/presentational/CustomizeModal";
import {priceFenToYuan, priceRangePreview, priceYuanToFen} from "@utils/priceConversion";
import { bulkEditShelfProductPrice } from "@sagas/shoppingMall/shoppingMallProduct";
import {useDispatch} from "react-redux";

const BulkEditProductPriceConfig = props => {
    const { goPreview, configInfo } = props
    const { hide, params } = useContext(CustomizeModalContext)
    const { productList } = params
    const [ priceType, setPriceType ] = useState(configInfo.priceType || 1)
    const [ config, setConfig ] = useState(configInfo.config || {type: 1, value: ''})
    const [ fixType, setFixType ] = useState(configInfo.fixType || 1)

    const handlePriceTypeChange = (e) => {
        setPriceType(e.target.value)
        setConfig({
            type: 1,
            value: '',
        })
    }
    const handleConfigChange = (key, value) => {
        setConfig({
            ...config,
            [key]: value
        })
    }
    const handleFixTypeChange = e => {
        setFixType(e.target.value)
    }

    const onSubmit = () => {
        if (!config.value) {
            notify('请输入改价金额', 'error')
            return;
        }
        const goNext = () => {
            goPreview({
                priceType,
                config,
                fixType
            })
        }
        if (priceType === 3 && productList.filter(prod => prod.skus.length > 1).length) {
            Modal.confirm({
                title: '选择商品中包含多规格商品， 统一改价后，不同规格设置的价格都将统一',
                cancelText: '返回',
                okText: '继续改价',
                onOk: () => {
                    goNext()
                },
            })
        } else {
            goNext()
        }
    }

    const disabledPriceType = (
        <div className="type-choose-box">
            <div className="type-button plus selected disabled">+</div>
            <div className="type-button minus disabled">-</div>
        </div>
    )

    return (
        <>
            <Row className="modal-line">
                <Col span={6}>改价方式</Col>
                <Col span={18}>
                    <Radio.Group
                        name="priceType"
                        value={priceType}
                        onChange={handlePriceTypeChange}
                        className="w-100"
                    >
                        <div className="modify-price-line">
                            <Radio className="radio-box" value={1}>在原价基础上</Radio>
                            { priceType === 1 ? (
                                <div className="type-choose-box">
                                    <div className={`type-button plus${config.type === 1 ? ' selected' : ''}`}
                                         onClick={() => handleConfigChange('type', 1)}
                                    >+</div>
                                    <div className={`type-button minus${config.type === 2 ? ' selected' : ''}`}
                                         onClick={() => handleConfigChange('type', 2)}
                                    >-</div>
                                </div>
                            ) : disabledPriceType }
                            <InputNumber
                                className="price-input-box"
                                placeholder="请输入数字"
                                min={0.01}
                                step={1}
                                precision={2}
                                value={priceType === 1 ? config.value : ''}
                                disabled={priceType !== 1}
                                onChange={value => handleConfigChange('value', value)}
                            />
                            <span>元</span>
                        </div>
                        <div className="modify-price-line">
                            <Radio className="radio-box" value={2}>在原价基础上</Radio>
                            { priceType === 2 ? (
                                <div className="type-choose-box">
                                    <div className={`type-button plus${config.type === 1 ? ' selected' : ''}`}
                                         onClick={() => handleConfigChange('type', 1)}
                                    >+</div>
                                    <div className={`type-button minus${config.type === 2 ? ' selected' : ''}`}
                                         onClick={() => handleConfigChange('type', 2)}
                                    >-</div>
                                </div>
                            ) : disabledPriceType }
                            <InputNumber
                                className="price-input-box"
                                placeholder="请输入数字"
                                min={0}
                                step={1}
                                precision={2}
                                value={priceType === 2 ? config.value : ''}
                                disabled={priceType !== 2}
                                onChange={value => handleConfigChange('value', value)}
                            />
                            <span>％</span>
                        </div>
                        <div className="modify-price-line">
                            <Radio className="radio-box" value={3}>统一改价为</Radio>
                            <InputNumber
                                className="price-input-box all-line"
                                placeholder="请输入数字"
                                min={0.01}
                                step={1}
                                precision={2}
                                value={priceType === 3 ? config.value : ''}
                                disabled={priceType !== 3}
                                onChange={value => handleConfigChange('value', value)}
                            />
                            <span>元</span>
                        </div>
                    </Radio.Group>
                </Col>
            </Row>
            { priceType === 3 ? null : (
                <Row className="modal-line">
                    <Col span={6}>分角处理</Col>
                    <Col span={18}>
                        <Radio.Group name="fixType"
                                     value={fixType}
                                     onChange={handleFixTypeChange}
                        >
                            <Radio value={1}>保留分角</Radio>
                            <Radio value={2}>抹去分</Radio>
                            <Radio value={3}>抹去分角</Radio>
                        </Radio.Group>
                    </Col>
                </Row>
            ) }
            <CustomizeModalButton
                onOk={onSubmit}
                cancelText="返回"
                onCancel={hide}
            />
        </>
    )
}


const BulkEditProductPricePreview = props => {
    const { backConfigPage, configInfo, callback, priceEditAction } = props
    const { hide, params } = useContext(CustomizeModalContext)
    const { productList } = params
    const dispatch = useDispatch()
    const [ tableData, setTableData ] = useState([])

    const columns = [ {
        title: '商品名称',
        dataIndex: 'custom_name',
        key: 'custom_name',
        render: (text, record) => {
            return {
                children: text || record.name,
                props: {
                    rowSpan: record.hasProperty ?
                        (record.skuIndex === 0 ? record.skus.length : 0) : 1
                },
            };
        },
    }, {
        title: '规格',
        dataIndex: 'hasProperty',
        key: 'hasProperty',
        render: (text, record) => text ? record.targetSku.name : '--',
    }, {
        title: '原价(元)',
        dataIndex: 'price',
        key: 'price',
        render: (text, record) => record.hasProperty ?
            record.targetSku.price : text,
    }, {
        title: '改价后(元)',
        dataIndex: 'priceAfterChange',
        key: 'priceAfterChange',
        render: (text, record) => record.hasProperty ?
            record.targetSku.priceAfterChange : text,
    } ]

    useEffect(() => {
        const _tableData = []
        productList.forEach(product => {
            let hasProperty = !(product.skus.length === 1 && product.skus[0].name === '')
            if (hasProperty) {
                (product.skus || []).forEach((sku, index) => {
                    let _sku = product.skus[index]
                    _tableData.push({
                        ...product,
                        skuIndex: index,
                        hasProperty,
                        targetSku: {
                            id: _sku.id,
                            name: _sku.name,
                            price: priceFenToYuan(_sku.price),
                            priceAfterChange: calcPriceAfterChange(priceFenToYuan(_sku.price)),
                        },
                        key: `product_${product.id}*${sku.id}`,
                    })
                })
            } else {
                _tableData.push({
                    ...product,
                    hasProperty,
                    price: priceFenToYuan(product.price_range[0]),
                    priceAfterChange: calcPriceAfterChange(priceFenToYuan(product.price_range[0])),
                    key: `product_${product.id}`,
                })
            }
        })
        setTableData(_tableData)
    }, [productList, configInfo])

    const calcPriceAfterChange = (price) => {
        const { priceType, config, fixType } = configInfo || {}
        let priceAfterChange = price - 0
        switch (priceType) {
            case 1:
                priceAfterChange = config.type === 1 ?
                    NP.plus(priceAfterChange, config.value - 0) :
                    NP.minus(priceAfterChange, config.value - 0)
                break;
            case 2:
                priceAfterChange = config.type === 1 ?
                    NP.times(priceAfterChange, NP.plus(1, NP.divide(config.value-0, 100))) :
                    NP.times(priceAfterChange, NP.minus(1, NP.divide(config.value-0, 100)))
                break;
            case 3:
                priceAfterChange = config.value - 0
                break;
            default:
                break;
        }
        if (priceType === 3) {
            return priceAfterChange
        } else {
            switch (fixType) {
                case 2:
                    priceAfterChange = NP.divide(parseInt(NP.times(priceAfterChange, 10)), 10)
                    break;
                case 3:
                    priceAfterChange = parseInt(priceAfterChange)
                    break;
                default:
                    break;
            }
            return priceAfterChange
        }
    }

    const getConfigInfoStr = () => {
        const { priceType, config, fixType } = configInfo || {}
        let str = ''
        switch (priceType) {
            case 1:
                str = `在原价基础上${config.type === 1 ? '+' : '-'}${config.value}元`
                break;
            case 2:
                str = `在原价基础上${config.type === 1 ? '+' : '-'}${config.value}%`
                break;
            case 3:
                str = `统一改价为${config.value}元`
                break;
            default:
                break;
        }
        if (priceType === 3) {
            return str
        } else {
            switch (fixType) {
                case 1:
                    str = `${str}，并保留分角`
                    break;
                case 2:
                    str = `${str}，并抹去分`
                    break;
                case 3:
                    str = `${str}，并抹去分角`
                    break;
                default:
                    break;
            }
            return str
        }
    }
    // 使用展示数据而不重新计算，保证保存的数据与展示数据一致
    const submitBulkProductPrice = () => {
        const prods = []
        let prod = null
        tableData.forEach(data => {
            if (data.hasProperty) {
                if (data.skuIndex === 0 && prod) {
                    prods.push(prod)
                    prod = null
                }
                if (!prod) {
                    prod = {
                        id: data.id,
                        skus: []
                    }
                }
                prod.skus.push({
                    id: data.targetSku.id,
                    custom_price: priceYuanToFen(data.targetSku.priceAfterChange)
                })
            } else {
                if (prod) {
                    prods.push(prod)
                    prod = null
                }
                prods.push({
                    id: data.id,
                    skus: [{
                        id: data.skus[0].id,
                        custom_price: priceYuanToFen(data.priceAfterChange)
                    }]
                })
            }
        })
        if (prod) {
            prods.push(prod)
        }
        priceEditAction(prods, () => {
            hide()
        })
    }

    return (
        <>
            <Row className="modal-line">
                <div className="preview-config-line">
                    <span>以下商品将 </span>
                    <span className="config-intro">
                            { getConfigInfoStr() }
                        </span>
                </div>
                <div className="preview-product-list">
                    <Table
                        className="w-100"
                        columns={columns}
                        pagination={false}
                        dataSource={tableData}
                    />
                </div>
            </Row>
            <CustomizeModalButton
                onOk={submitBulkProductPrice}
                onCancel={backConfigPage}
            />
        </>
    )
}

const BulkEditProductPriceContainer = props => {
    const [ configInfo, setConfigInfo ] = useState({})
    const [ isPreview, setIsPreview ] = useState(false)
    const goPreview = (config) => {
        setIsPreview(true)
        setConfigInfo(config)
    }
    const backConfigPage = () => {
        setIsPreview(false)
    }
    return isPreview ? (
        <BulkEditProductPricePreview
            {...props}
            configInfo={configInfo}
            backConfigPage={backConfigPage}
        />
    ) : (
        <BulkEditProductPriceConfig
            {...props}
            configInfo={configInfo}
            goPreview={goPreview}
        />
    )
}

export const BulkEditProductPriceModal = forwardRef((props, ref) => {
    return (
        <CustomizeModal title="批量改价" ref={ref} className="bulk-edit-product-price-modal">
            <BulkEditProductPriceContainer {...props} />
        </CustomizeModal>
    )
})

export const SingleEditProductPriceContent = props => {
    const { callback, priceEditAction } = props
    const { hide, params } = useContext(CustomizeModalContext)
    const { productInfo } = params
    const [ customPrice, setCustomPrice ] = useState({})
    const [ data, setData ] = useState(null)
    const dispatch = useDispatch()
    useEffect(() => {
        let hasProperty = !(productInfo.skus.length === 1 && productInfo.skus[0].name === '')
        let _data = {
            ...productInfo,
            hasProperty,
            skus: productInfo.skus.map(sku => ({
                ...sku,
                price: customPrice[sku.id] === undefined ? sku.price : customPrice[sku.id],
                key: sku.id
            }))
        }
        setData(_data)
    }, [customPrice, productInfo])

    const columns = [ {
        title: '规格属性',
        dataIndex: 'name',
        key: 'name',
    }, {
        title: '价格（元）',
        dataIndex: 'price',
        key: 'price',
        render: (text, record) =>
            <InputNumber
                min={0.01}
                max={100000000}
                step={1}
                precision={2}
                value={priceFenToYuan(text)}
                className="w-100"
                onChange={handleSkuPriceChange.bind(this, record.id)}
            />
    }]

    const handleSkuPriceChange = (skuId, value) => {
        setCustomPrice({
            ...customPrice,
            [skuId]: priceYuanToFen(value),
        })
    }

    const submitProductPrice = () => {
        if (data.skus.filter(sku => !sku.price).length) {
            notify('请输入商品价格')
            return ;
        }
        priceEditAction(data, () => {
            hide()
        })
    }

    return data ? (
        <>
            <Row className="modal-line">
                <Col span={6}>商品名称</Col>
                <Col span={18}>{productInfo.name}</Col>
            </Row>
            <Row className="modal-line">
                { data.hasProperty ? (
                    <Table
                        className="w-100"
                        columns={columns}
                        pagination={false}
                        dataSource={data.skus}
                    />
                ) : (
                    <>
                        <Col span={6}>商品价格</Col>
                        <Col span={18}>
                            <InputNumber
                                min={0.01}
                                max={100000000}
                                step={1}
                                precision={2}
                                value={priceFenToYuan(data.skus[0].price)}
                                className="w-100"
                                onChange={handleSkuPriceChange.bind(this, data.skus[0].id)}
                            />
                        </Col>
                    </>
                ) }
            </Row>
            <CustomizeModalButton
                onOk={submitProductPrice}
                onCancel={hide}
            />
        </>
    ) : null
}

export const SingleEditProductPriceModal = forwardRef((props, ref) => {
    return (
        <CustomizeModal title="修改价格" ref={ref}>
            <SingleEditProductPriceContent {...props} />
        </CustomizeModal>
    )
})